package com.luo.d3s.ext.aop.config;

import com.luo.d3s.ext.aop.exception.aspect.D3sExceptionAnnoHandlerAspect;
import com.luo.d3s.ext.aop.exception.aspect.D3sExceptionWebControllerAdvice;
import com.luo.d3s.ext.aop.exception.handler.D3sDefaultExceptionHandler;
import com.luo.d3s.ext.aop.exception.handler.D3sExceptionHandler;
import com.luo.d3s.ext.aop.log.aspect.D3sLogServiceAspect;
import com.luo.d3s.ext.aop.log.aspect.D3sWebLogAspect;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.RestController;

/**
 * D3s Aop 自动配置
 *
 * @author luohq
 * @date 2023-01-29 16:23
 */
@Configuration
@EnableConfigurationProperties({D3sAopProps.class})
public class D3sAopAutoConfiguration {

    /**
     * 异常处理AOP增强配置
     */
    @Configuration
    @ConditionalOnProperty(name = "d3s.aop.exception.enabled", havingValue = "true", matchIfMissing = true)
    static class D3sAopExceptionHandleAutoConfiguration {

        @Bean
        @ConditionalOnMissingBean
        static D3sExceptionHandler d3sExceptionHandler(D3sAopProps d3sAopProps) {
            return new D3sDefaultExceptionHandler(d3sAopProps.getException());
        }

        @Bean
        @Order(20)
        static D3sExceptionAnnoHandlerAspect d3sExceptionAnnoHandlerAspect(D3sAopProps d3sAopProps, D3sExceptionHandler d3sExceptionHandler) {
            return new D3sExceptionAnnoHandlerAspect(d3sAopProps, d3sExceptionHandler);
        }

        @Bean
        @ConditionalOnClass({RestController.class})
        @ConditionalOnProperty(prefix = D3sAopProps.PREFIX, name = "exception.enable-web-exception-handle", havingValue = "true", matchIfMissing = true)
        @ConditionalOnMissingBean
        @Order(20)
        static D3sExceptionWebControllerAdvice d3sExceptionWebControllerAdvice(D3sAopProps d3sAopProps, D3sExceptionHandler d3sExceptionHandler) {
            return new D3sExceptionWebControllerAdvice(d3sAopProps, d3sExceptionHandler);
        }
    }


    /**
     * 日志AOP增强配置
     */
    @Configuration
    @ConditionalOnProperty(name = "d3s.aop.log.enabled", havingValue = "true", matchIfMissing = true)
    static class D3sLogAutoConfiguration {

        @Bean
        @Order(10)
        static D3sLogServiceAspect d3sLogServiceAspect(D3sAopProps d3sAopProps) {
            return new D3sLogServiceAspect(d3sAopProps);
        }

        @Bean
        @ConditionalOnClass({RestController.class})
        @Order(10)
        static D3sWebLogAspect d3sWebLogAspect(D3sAopProps d3sAopProps) {
            return new D3sWebLogAspect(d3sAopProps);
        }
    }

}
